package com.leo.base.db;

import com.leo.base.util.SpringContextUtil;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 将所有mapper中sql的操作类型进行缓存
 */
@Component
public class SqlDmlCacheSmartLifecycle implements SmartLifecycle {

    private static Map<String, String> dmlTypeMap = new HashMap<>();

    private boolean isRunning = false;

    @Override
    public void start() {
        isRunning = true;
        SqlSessionFactory sqlSessionFactory;
        Map<String, SqlSessionFactory> beansOfType = SpringContextUtil.getBeansOfType(SqlSessionFactory.class);
        if (null == beansOfType || beansOfType.isEmpty()) {
            return;
        }
        for (Map.Entry<String, SqlSessionFactory> entry : beansOfType.entrySet()) {
            sqlSessionFactory = entry.getValue();
            Collection<MappedStatement> mappedStatements = sqlSessionFactory.getConfiguration().getMappedStatements();
            Iterator<MappedStatement> iterator = mappedStatements.iterator();
            while (iterator.hasNext()) {
                MappedStatement next = iterator.next();
                SqlCommandType sqlCommandType = next.getSqlCommandType();
                String methodName = next.getId().substring(next.getId().lastIndexOf(".") + 1);
                SqlDmlCacheSmartLifecycle.dmlTypeMap.put(methodName, sqlCommandType.name());
            }
        }
    }

    @Override
    public void stop() {
        isRunning = false;
    }

    @Override
    public boolean isRunning() {
        return isRunning;
    }

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public void stop(Runnable callback) {
        callback.run();
        isRunning = false;
    }

    @Override
    public int getPhase() {
        return 0;
    }

    public static String getSqlDmlType(String methodName) {
        return dmlTypeMap.get(methodName);
    }
}
